<template>
  <div ref="viewerContainer" class="viewer-container">
    <!-- tools Instructions dialog start -->
    <el-dialog
        v-model="dialogVisible"
        title="使用说明"
        width="30%"
        align-center
    >
      <div>
        <div style="font-size: 18px;font-weight: 600;">具体工具说明：</div>
        <el-timeline>
          <el-timeline-item
              v-for="(item, index) in Mouse"
              :key="index"
              :timestamp="item.content"
          >
            {{ item.title }}
          </el-timeline-item>
        </el-timeline>
      </div>
    </el-dialog>
    <!-- tools Instructions dialog end -->

    <div>
      <div id="content">
        <div id="demo-toolbar">
          <div>
            <el-button style="margin-top: 16px;border:none;background-color: transparent" @click="openCrosshairs">
              <el-icon :size="25">
                <Rank />
              </el-icon>
            </el-button>
            <el-button style="margin-top: 16px;border:none;background-color: transparent" @click="openBrush">
              <el-icon :size="25">
                <Brush />
              </el-icon>
            </el-button>
          </div>
          <!-- Insert buttons/dropdowns/etc here during demo -->
        </div>
        <div style="width: 100%;height: 20px"></div>

        <div style="position: fixed;left: 980px;top:133px;z-index:9999">
          <div>
            <div style="font-size: 18px;font-weight: 600;">鼠标操作说明：</div>
            <el-timeline>
              <el-timeline-item
                  v-for="(item, index) in Mouse"
                  :key="index"
                  :timestamp="item.content"
                  style="color: white !important;"
              >
                <span style="color: white"> {{ item.title }}</span>
              </el-timeline-item>
            </el-timeline>
          </div>
        </div>
        <div id="brush-bar" style="height: 30px;width: 100%;position: fixed;left: 1169px;top:133px;display: none">
          <div>
            <div style="font-size: 18px;font-weight: 600;">具体工具说明：</div>
            <el-timeline>
              <el-timeline-item
                  v-for="(item, index) in Tools"
                  :key="index"
                  :timestamp="item.content"
                  style="color: white !important;"
              >
                <span style="color: white"> {{ item.title }}</span>
              </el-timeline-item>
            </el-timeline>
            <el-timeline>
              <el-timeline-item
                  v-for="(item, index) in Tools2"
                  :key="index"
                  :timestamp="item.content"
                  style="color: white !important;"
              >
                <span style="color: white"> {{ item.title }}</span>
              </el-timeline-item>
            </el-timeline>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {onMounted, ref} from "vue";
import {
  RenderingEngine,
  Types,
  Enums,
  setVolumesForViewports,
  volumeLoader,
  getRenderingEngine
} from '@cornerstonejs/core';

import initDemo from '../assets/utils/demo/helpers/initDemo'
import addDropdownToToolbar from '../assets/utils/demo/helpers/addDropdownToToolbar'
import addSliderToToolbar from '../assets/utils/demo/helpers/addSliderToToolbar'
import setCtTransferFunctionForVolumeActor from '../assets/utils/demo/helpers/setCtTransferFunctionForVolumeActor'

import * as cornerstoneTools from '@cornerstonejs/tools';
import {segmentation, SegmentationDisplayTool, ToolGroupManager} from "@cornerstonejs/tools";
import router from "@/router";
import Analysis from "@/components/analysis/Label"
import {ArrowRightBold, EditPen, Brush, Rank} from "@element-plus/icons-vue";
import addButtonToToolbar from "../assets/utils/demo/helpers/addButtonToToolbar";
import setPetColorMapTransferFunctionForVolumeActor
  from "../assets/utils/demo/helpers/setPetColorMapTransferFunctionForVolumeActor";
import createImageIdsAndCacheMetaData from "@/assets/utils/demo/helpers/createImageIdsAndCacheMetaData"
export default {
  name: 'LabelViews',
  components:{
    Analysis,
    EditPen,
    Brush,
    Rank
  },
  setup() {
    const Mouse = [
      {
        title: '鼠标左键点击拖动',
        content: '可使用对应选择的工具',
      },
      {
        title: '鼠标右键点击拖动',
        content: '可改变影像的大小',
      },
      {
        title: '鼠标滚轮滑动',
        content: '滚动影像层',
      },
      {
        title: '鼠标滚轮点击',
        content: '调整影像位置',
      },
    ]

    const Tools = [
      {
        title: 'CircularBrush',
        content: '圆形画笔',
      },
      {
        title: 'CircularEraser',
        content: '圆形橡皮擦',
      },
      {
        title: 'SphereBrush',
        content: '球体画笔',
      },
      {
        title: 'SphereEraser',
        content: '球体橡皮擦',
      },
    ]
    const Tools2 = [
      {
        title: 'ThresholdBrush',
        content: '阈值画笔',
      },
      {
        title: 'RectangleScissor',
        content: '长方形剪刀',
      },
      {
        title: 'CircleScissor',
        content: '圆形剪刀',
      },
      {
        title: 'SphereScissor',
        content: '球体剪刀',
      },
    ]

    const Tools3 = [
      {
        title: 'PaintFill',
        content: '全部填充',
      },
    ]

    const drawer = ref(false)
    const direction = ref('ltr')

    const dialogVisible = ref(false)

    const radio = ref("修改label")

    const {
      CrosshairsTool,
      ToolGroupManager,
      StackScrollMouseWheelTool,
      Enums: csToolsEnums,
      segmentation,
      utilities: cstUtils,
      SegmentationDisplayTool,
      RectangleScissorsTool,
      SphereScissorsTool,
      CircleScissorsTool,
      BrushTool,
      PaintFillTool,
      PanTool,
      ZoomTool,
      WindowLevelTool,
    } = cornerstoneTools;

    const { ViewportType } = Enums;
    const { segmentation: segmentationUtils } = cstUtils;
    const { MouseBindings } = csToolsEnums;

    // 创建volume、派生volume和工具集合的唯一标识码
    const volumeId = `cornerstoneStreamingImageVolume:CT_VOLUME_ID`;
    const segmentationId = 'MY_SEGMENTATION_ID';
    const toolGroupId = 'MY_TOOLGROUP_ID';

    const toolGroup = ToolGroupManager.createToolGroup(toolGroupId);

    const viewportId1 = 'CT_AXIAL';
    const viewportId2 = 'CT_SAGITTAL';
    const viewportId3 = 'CT_CORONAL';

    const renderingEngineId = 'myRenderingEngine';


    const viewportColors = {
      [viewportId1]: 'rgb(200, 0, 0)',
      [viewportId2]: 'rgb(200, 200, 0)',
      [viewportId3]: 'rgb(0, 200, 0)',
    };

    const viewportReferenceLineControllable = [
      viewportId1,
      viewportId2,
      viewportId3,
    ];

    const viewportReferenceLineDraggableRotatable = [
      viewportId1,
      viewportId2,
      viewportId3,
    ];

    const viewportReferenceLineSlabThicknessControlsOn = [
      viewportId1,
      viewportId2,
      viewportId3,
    ];

    function getReferenceLineColor(viewportId) {
      return viewportColors[viewportId];
    }

    function getReferenceLineControllable(viewportId) {
      const index = viewportReferenceLineControllable.indexOf(viewportId);
      return index !== -1;
    }

    function getReferenceLineDraggableRotatable(viewportId) {
      const index = viewportReferenceLineDraggableRotatable.indexOf(viewportId);
      return index !== -1;
    }

    function getReferenceLineSlabThicknessControlsOn(viewportId) {
      const index =
          viewportReferenceLineSlabThicknessControlsOn.indexOf(viewportId);
      return index !== -1;
    }

    onMounted(async () => {
      const blendModeOptions = {
        MIP: 'Maximum Intensity Projection',
        MINIP: 'Minimum Intensity Projection',
        AIP: 'Average Intensity Projection',
      };

      await initDemo();

      await run();
    });

    async function addSegmentationsToState(volumeId, segmentationId, csToolsEnums ) {
      const segmentationVolume = await volumeLoader.createAndCacheDerivedVolume(
          volumeId,
          {
            volumeId: segmentationId,
          }
      );

      // Add the segmentations to state
      segmentation.addSegmentations([
        {
          segmentationId,
          representation: {
            type: csToolsEnums.SegmentationRepresentations.Labelmap,
            data: {
              volumeId: segmentationId,
            },
          },
        },
      ]);
    }

    function openBrush(){
      // cornerstoneTools.removeTool(StackScrollMouseWheelTool)
      console.log(123)
      closeCrosshairs();
      createTools(renderingEngineId)
      // closeBrush();
      document.getElementById("brush-bar").style.display = 'block'
    }

    function openCrosshairs(){
      createCrosshairs();
    }
    // 创建画笔工具
    async function createTools(renderingEngineId){
      // 定义画笔名字
      const brushInstanceNames = {
        CircularBrush: 'CircularBrush',
        CircularEraser: 'CircularEraser',
        SphereBrush: 'SphereBrush',
        SphereEraser: 'SphereEraser',
        ThresholdBrush: 'ThresholdBrush',
      };

      const brushStrategies = {
        [brushInstanceNames.CircularBrush]: 'FILL_INSIDE_CIRCLE',
        [brushInstanceNames.CircularEraser]: 'ERASE_INSIDE_CIRCLE',
        [brushInstanceNames.SphereBrush]: 'FILL_INSIDE_SPHERE',
        [brushInstanceNames.SphereEraser]: 'ERASE_INSIDE_SPHERE',
        [brushInstanceNames.ThresholdBrush]: 'THRESHOLD_INSIDE_CIRCLE',
      };

      const brushValues = [
        brushInstanceNames.CircularBrush,
        brushInstanceNames.CircularEraser,
        brushInstanceNames.SphereBrush,
        brushInstanceNames.SphereEraser,
        brushInstanceNames.ThresholdBrush,
      ];

      const optionsValues = [
        ...brushValues,
        RectangleScissorsTool.toolName,
        CircleScissorsTool.toolName,
        SphereScissorsTool.toolName,
        PaintFillTool.toolName,
      ];

      addDropdownToToolbar({
        options: { values: optionsValues, defaultValue: BrushTool.toolName },
        onSelectedValueChange: (nameAsStringOrNumber) => {
          const name = String(nameAsStringOrNumber);
          const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);

          // Set the currently active tool disabled
          const toolName = toolGroup.getActivePrimaryMouseButtonTool();

          if (toolName) {
            toolGroup.setToolDisabled(toolName);
          }

          if (brushValues.includes(name)) {
            toolGroup.setToolActive(name, {
              bindings: [{ mouseButton: MouseBindings.Primary }],
            });
          } else {
            const toolName = name;

            toolGroup.setToolActive(toolName, {
              bindings: [{ mouseButton: MouseBindings.Primary }],
            });
          }
        },
      });

      const thresholdOptions = ['CT Fat: (-150, -70)', 'CT Bone: (200, 1000)'];

      addDropdownToToolbar({
        options: { values: thresholdOptions, defaultValue: thresholdOptions[0] },
        onSelectedValueChange: (nameAsStringOrNumber) => {
          const name = String(nameAsStringOrNumber);

          let threshold;
          if (name === thresholdOptions[0]) {
            threshold = [-150, -70];
          } else if (name == thresholdOptions[1]) {
            threshold = [100, 1000];
          }

          segmentationUtils.setBrushThresholdForToolGroup(toolGroupId, threshold);
        },
      });

      addSliderToToolbar({
        title: 'Brush Size',
        range: [5, 50],
        defaultValue: 25,
        onSelectedValueChange: (valueAsStringOrNumber) => {
          const value = Number(valueAsStringOrNumber);
          segmentationUtils.setBrushSizeForToolGroup(toolGroupId, value);
        },
      });

      // Add tools to Cornerstone3D
      cornerstoneTools.addTool(PanTool);
      cornerstoneTools.addTool(ZoomTool);
      cornerstoneTools.addTool(StackScrollMouseWheelTool);
      cornerstoneTools.addTool(SegmentationDisplayTool);
      cornerstoneTools.addTool(RectangleScissorsTool);
      cornerstoneTools.addTool(CircleScissorsTool);
      cornerstoneTools.addTool(SphereScissorsTool);
      cornerstoneTools.addTool(PaintFillTool);
      cornerstoneTools.addTool(BrushTool);
      cornerstoneTools.addTool(WindowLevelTool);

      toolGroup.addTool(PanTool.toolName);
      toolGroup.addTool(ZoomTool.toolName);
      toolGroup.addTool(StackScrollMouseWheelTool.toolName);

      toolGroup.addTool(SegmentationDisplayTool.toolName);
      toolGroup.addTool(RectangleScissorsTool.toolName);
      toolGroup.addTool(CircleScissorsTool.toolName);
      toolGroup.addTool(SphereScissorsTool.toolName);
      toolGroup.addTool(PaintFillTool.toolName);


      toolGroup.addToolInstance(
          brushInstanceNames.CircularBrush,
          BrushTool.toolName,
          {
            activeStrategy: brushStrategies.CircularBrush,
          }
      );
      toolGroup.addToolInstance(
          brushInstanceNames.CircularEraser,
          BrushTool.toolName,
          {
            activeStrategy: brushStrategies.CircularEraser,
          }
      );
      toolGroup.addToolInstance(
          brushInstanceNames.SphereBrush,
          BrushTool.toolName,
          {
            activeStrategy: brushStrategies.SphereBrush,
          }
      );
      toolGroup.addToolInstance(
          brushInstanceNames.SphereEraser,
          BrushTool.toolName,
          {
            activeStrategy: brushStrategies.SphereEraser,
          }
      );
      toolGroup.addToolInstance(
          brushInstanceNames.ThresholdBrush,
          BrushTool.toolName,
          {
            activeStrategy: brushStrategies.ThresholdBrush,
          }
      );

      toolGroup.setToolEnabled(SegmentationDisplayTool.toolName);

      toolGroup.setToolActive(brushInstanceNames.CircularBrush, {
        bindings: [{ mouseButton: MouseBindings.Primary }],
      });

      toolGroup.setToolActive(PanTool.toolName, {
        bindings: [
          {
            mouseButton: MouseBindings.Auxiliary, // Middle Click
          },
        ],
      });
      toolGroup.setToolActive(ZoomTool.toolName, {
        bindings: [
          {
            mouseButton: MouseBindings.Secondary, // Right Click
          },
        ],
      });

      toolGroup.setToolActive(StackScrollMouseWheelTool.toolName);
      toolGroup.addViewport(viewportId1, renderingEngineId);
      toolGroup.addViewport(viewportId2, renderingEngineId);
      toolGroup.addViewport(viewportId3, renderingEngineId);
    }

    async function closeCrosshairs(){
      toolGroup.setToolDisabled(StackScrollMouseWheelTool.toolName,)
      toolGroup.setToolDisabled(CrosshairsTool.toolName,)
      cornerstoneTools.removeTool(StackScrollMouseWheelTool)
      cornerstoneTools.removeTool(CrosshairsTool)
      const selectElements = document.querySelectorAll('select');
      selectElements.forEach(function(selectElement){
        selectElement.remove();
      });
    }

    async function createCrosshairs(renderingEngineId){
      addDropdownToToolbar({
        options: {
          values: [
            'Maximum Intensity Projection',
            'Minimum Intensity Projection',
            'Average Intensity Projection',
          ],
          defaultValue: 'Maximum Intensity Projection',
        },
        onSelectedValueChange: function(selectedValue) {
          let blendModeToUse;
          switch (selectedValue) {
            case blendModeOptions.MIP:
              blendModeToUse = Enums.BlendModes.MAXIMUM_INTENSITY_BLEND;
              break;
            case blendModeOptions.MINIP:
              blendModeToUse = Enums.BlendModes.MINIMUM_INTENSITY_BLEND;
              break;
            case blendModeOptions.AIP:
              blendModeToUse = Enums.BlendModes.AVERAGE_INTENSITY_BLEND;
              break;
            default:
              throw new Error('undefined orientation option');
          }

          const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);

          const crosshairsInstance = toolGroup.getToolInstance(
              CrosshairsTool.toolName
          );
          const oldConfiguration = crosshairsInstance.configuration;

          crosshairsInstance.configuration = {
            ...oldConfiguration,
            slabThicknessBlendMode: blendModeToUse,
          };

          // Update the blendMode for actors to instantly reflect the change
          toolGroup.viewportsInfo.forEach(function(_ref) {
            const viewportId = _ref.viewportId, renderingEngineId = _ref.renderingEngineId;
            const renderingEngine = getRenderingEngine(renderingEngineId);
            const viewport = renderingEngine.getViewport(viewportId);

            viewport.setBlendMode(blendModeToUse);
            viewport.render();
          });
        },
      });

      cornerstoneTools.addTool(StackScrollMouseWheelTool);
      cornerstoneTools.addTool(CrosshairsTool);
      // Define tool groups to add the segmentation display tool to

      // For the crosshairs to operate, the viewports must currently be
      // added ahead of setting the tool active. This will be improved in the future.
      toolGroup.addViewport(viewportId1, renderingEngineId);
      toolGroup.addViewport(viewportId2, renderingEngineId);
      toolGroup.addViewport(viewportId3, renderingEngineId);

      // Manipulation Tools
      toolGroup.addTool(StackScrollMouseWheelTool.toolName);
      // Add Crosshairs tool and configure it to link the three viewports
      // These viewports could use different tool groups. See the PET-CT example
      // for a more complicated used case.

      const isMobile = window.matchMedia('(any-pointer:coarse)').matches;

      toolGroup.addTool(CrosshairsTool.toolName, {
        getReferenceLineColor,
        getReferenceLineControllable,
        getReferenceLineDraggableRotatable,
        getReferenceLineSlabThicknessControlsOn,
        mobile: {
          enabled: isMobile,
          opacity: 0.8,
          handleRadius: 9,
        },
      });

      toolGroup.setToolActive(CrosshairsTool.toolName, {
        bindings: [{ mouseButton: MouseBindings.Primary }],
      });
      // As the Stack Scroll mouse wheel is a tool using the `mouseWheelCallback`
      // hook instead of mouse buttons, it does not need to assign any mouse button.
      toolGroup.setToolActive(StackScrollMouseWheelTool.toolName);
    }

    async function run() {
      // 初始化工具

      // 创建窗口
      const content = document.getElementById('content');
      const viewportGrid = document.createElement('div');

      const element1 = document.createElement('div');
      const element2 = document.createElement('div');
      const element3 = document.createElement('div');
      element1.style.width = '49.5%';
      element1.style.height = '300.5px';
      element1.style.border = '1px solid #25556e'
      element2.style.width = '49.5%';
      element2.style.height = '300.5px';
      element2.style.float = 'left'
      element2.style.border = '1px solid #25556e'
      element2.style.marginTop = '20px'
      element3.style.width = '49.5%';
      element3.style.height = '300.5px';
      element3.style.marginLeft = '0.33%'
      element3.style.border = '1px solid #25556e'
      element3.style.float = 'left'
      element3.style.marginTop = '20px'

      element1.oncontextmenu = (e) => e.preventDefault();
      element2.oncontextmenu = (e) => e.preventDefault();
      element3.oncontextmenu = (e) => e.preventDefault();

      viewportGrid.appendChild(element1);
      viewportGrid.appendChild(element2);
      viewportGrid.appendChild(element3);

      content.appendChild(viewportGrid);

      const imageIds = [
        "wadouri:https://plantarflex.github.io/cornerstoneTools-SyncBrushTool/data/CT000012.dcm",
      ]

      console.log(imageIds)
      // Define a volume in memory
      const volume = await volumeLoader.createAndCacheVolume(volumeId, {
        imageIds,
      });
      // Add some segmentations based on the source data volume
      await addSegmentationsToState(volumeId,segmentationId,csToolsEnums );

      // Instantiate a rendering engine
      const renderingEngine = new RenderingEngine(renderingEngineId);

      // 创建画笔工具
      // await createTools(renderingEngineId)
      // await createCrosshairs(viewportId1, viewportId2, viewportId3, renderingEngineId, toolGroupId)


      // Set the volume to load
      volume.load();

      const viewportInputArray = [
        {
          viewportId: viewportId1,
          type: ViewportType.ORTHOGRAPHIC,
          element: element1,
          defaultOptions: {
            orientation: Enums.OrientationAxis.AXIAL,
            background: [0, 0, 0],
          },
        },
        {
          viewportId: viewportId2,
          type: ViewportType.ORTHOGRAPHIC,
          element: element2,
          defaultOptions: {
            orientation: Enums.OrientationAxis.SAGITTAL,
            background: [0, 0, 0],
          },
        },
        {
          viewportId: viewportId3,
          type: ViewportType.ORTHOGRAPHIC,
          element: element3,
          defaultOptions: {
            orientation: Enums.OrientationAxis.CORONAL,
            background: [0, 0, 0],
          },
        },
      ];


      renderingEngine.setViewports(viewportInputArray);

      // Set volumes on the viewports
      await setVolumesForViewports(
          renderingEngine,
          [{
            volumeId,
            callback: setCtTransferFunctionForVolumeActor,
          }],
          [viewportId1, viewportId2, viewportId3]
      );


      await createCrosshairs(renderingEngineId);
      // await createTools(renderingEngineId)
      await segmentation.addSegmentationRepresentations(toolGroupId, [
        {
          segmentationId,
          type: csToolsEnums.SegmentationRepresentations.Labelmap,
        },
      ]);

      // Render the image
      renderingEngine.renderViewports([viewportId1, viewportId2, viewportId3]);

      await closeCrosshairs();

      let fused = false;
      const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use
      const ptVolumeName = 'PT_VOLUME_ID';
      const ptVolumeId = `${volumeLoaderScheme}:${ptVolumeName}`;

      addButtonToToolbar({
        title: '展示label',
        onClick: function onClick() {
          // Get the rendering engine
          const renderingEngine = getRenderingEngine(renderingEngineId);

          // Get the volume viewport
          const viewport = renderingEngine.getViewport(viewportId1);
          if (fused) {
            // Removes the PT actor from the scene
            viewport.removeVolumeActors([ptVolumeId], true);

            fused = false;
          } else {
            // Add the PET volume to the viewport. It is in the same DICOM Frame Of Reference/worldspace
            // If it was in a different frame of reference, you would need to register it first.
            viewport.addVolumes(
                [
                  {
                    volumeId: ptVolumeId,
                    callback: setPetColorMapTransferFunctionForVolumeActor,
                  },
                ],
                true
            );

            fused = true;
          }
        }
      });

      await pt(ptVolumeId);
    }
    const wadoRsRoot = 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb';
    const StudyInstanceUID =
        '1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463';
    async function pt(ptVolumeId) {
      const ptImageIds = await createImageIdsAndCacheMetaData({
        StudyInstanceUID,
        SeriesInstanceUID:
            '1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561',
        wadoRsRoot,
      });
      console.log(ptImageIds)

      const ptVolume = await volumeLoader.createAndCacheVolume(ptVolumeId, {
        imageIds: ptImageIds,
      });


      // Set the volume to load
      ptVolume.load();
    }


    return {
      drawer,
      direction,
      Analysis,
      dialogVisible,
      Mouse,
      Tools,
      radio,
      ArrowRightBold,
      openBrush,
      createCrosshairs,
      openCrosshairs,
      Tools2,
      Tools3
    };
  },
};
</script>

<style scoped>
.viewer-container {
  width: 100%;
  height: 100%;
  background-color: rgba(24, 24, 24, 1);
}
.analysis_box{
  width: 450px;
  height: 95%;
  background-color: #020327;
}
label{
  color: white !important;
}
.gui_controller{
  width: 272px;
  height: 41px;
  position: fixed;
  right: -5px;
  text-align: center;
  top: 70px;
}
.analysis_controller{
  position: fixed;
  top: 280px;
  word-wrap: break-word;
  width: 30px;
  border-radius: 0 10px 10px 0;
  text-align: center;
  z-index: 999999;
}
#demo-toolbar label{
  margin-left: 20px;
}
#demo-toolbar{
  position: fixed;
  left: 959px;
  top: 52px;
}
div{
  color: white !important;
}
.el-timeline {
  margin: 10px;
  /* font-size: var(--el-font-size-base); */
  list-style: none;
  padding: 0;
  width: 142px;
  float: left;
}
</style>
